package hillclimbing;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;

public class Hillclimbing {
   
    PlaatsenMatrix afstanden;
    int beginStad;

    String result = new String();
    
    ArrayList<Integer> route;
    int steden_bezocht = 0;
    int kosten = 0;
    
    public Hillclimbing(PlaatsenMatrix matrix, int beginStad) {
        
        afstanden = matrix;
        this.beginStad = beginStad;        
    }
    public String start () {
        
        route = new ArrayList();
        route.add(beginStad);
        steden_bezocht++;
        search(beginStad);
	
        result += "# steden: "+steden_bezocht+"\n";
        result += "Oplossing: "+route.toString() + "// Kosten: "+kosten+"\n";
	
        return result;         
    }  
    public void wisselOplossing( int max_pogingen){
	
	System.out.println("Proberen te wisselen! x"+max_pogingen);
	int[] tmpRoute = new int[route.size()];
	int maxrand = route.size() -2;
	Random ran = new Random();
	int i=0;
	for(Integer r : route){
	    tmpRoute[i] = (int) r;
	    i++;
	}
	for(int poging=0; poging < max_pogingen;poging++){
	    int wisselvan, wisselnaar;
	    int kosten=0;
	    int tmp = 0;
	    String output="";
	    wisselvan = ran.nextInt(maxrand)+1;
	    wisselnaar = ran.nextInt(maxrand)+1;
	    while(wisselnaar == wisselvan){
		wisselnaar = ran.nextInt(maxrand)+1;
	    }
	    tmp = tmpRoute[wisselvan];
	    tmpRoute[wisselvan] = tmpRoute[wisselnaar];
	    tmpRoute[wisselnaar] = tmp;
	    
	    for(int out=0;out<tmpRoute.length;out++){
		output += tmpRoute[out]+", ";
		if(out+1 < tmpRoute.length){
		kosten += afstanden.getAfstand(tmpRoute[out],tmpRoute[out+1]);
		}
	    }
	    System.out.println(output + " kosten:"+kosten + "	verschil: "+ (kosten - this.kosten));
	    if(kosten < this.kosten){
		System.out.println("Betere oplossing gevonden!");
	    }
	    
	}
    }
    public void search (int startPunt) {
        
        int huidigePositie = startPunt;
        
        while (steden_bezocht != afstanden.getAantalSteden()) {
	    
	    int lowestDistance = afstanden.getMaximaleAfstand()+1;
            int volgendeStad = -1;
            for (int i=0; i < afstanden.getAantalSteden(); i++) {
                if (!route.contains(i)) {
                    int tempDistance = afstanden.getAfstand(huidigePositie , i); // f = g + h
                    if (tempDistance < lowestDistance) {
                        lowestDistance = tempDistance;
                        volgendeStad = i;
                }                    }

            }
            kosten += lowestDistance;
            route.add(volgendeStad);
            huidigePositie = volgendeStad;
            steden_bezocht++;
        }

        kosten += afstanden.getAfstand(huidigePositie, beginStad);
        route.add(beginStad);
        steden_bezocht++;
    }
    
    public static void main(String[] args){
	PlaatsenMatrix matrix = new PlaatsenMatrix(8);
	System.out.println(matrix.toString());
	Hillclimbing h = new Hillclimbing(matrix, 0);
	System.out.println(h.start());
	h.wisselOplossing(10);
	
    }
    
}